#ifndef __BASE_BASE_H__
#define __BASE_BASE_H__

#include "typedef.h"

namespace base {
  template <typename T>
  T min(T d1, T d2) { return d1 > d2 ? d2 : d1; }

  template <typename T>
  T max(T d1, T d2) { return d1 > d2 ? d1 : d2; }

  struct Point {
    dtype x,y;
    Point();
    Point(dtype _x, dtype _y);
    void clear();
    void reset(dtype _x, dtype _y);
    void offset(dtype dx, dtype dy);
  };

  struct Size {
    dtype w,h;
    Size();
    Size(dtype _w, dtype _h);
    void clear();
    void reset(dtype _w, dtype _h);
    void offset(dtype dw, dtype dh);
  };

  struct Inset {
    dtype l,t,r,b;
    Inset();
    Inset(dtype _l, dtype _t, dtype _r, dtype _b);
    void clear();
    void reset(dtype _l, dtype _t, dtype _r, dtype _b);
    void offset(dtype dl, dtype dt, dtype dr, dtype db);
  };
  
  struct Rect {
    dtype x,y,w,h;
    Rect();
    Rect(dtype _x, dtype _y, dtype _w, dtype _h);
    void clear();
    void reset(dtype _x, dtype _y, dtype _w, dtype _h);
    void set_boundary(dtype l, dtype t, dtype r, dtype b);
    void set_point(dtype _x, dtype _y);
    void set_size(dtype _w, dtype _h);
    void Inset(const struct Inset &inset);
    void Inset(dtype l, dtype t, dtype r, dtype b);
    void offset(dtype dx, dtype dy, dtype dw, dtype dh);
    void offset_point(dtype dx, dtype dy);
    void offset_size(dtype dw, dtype dh);
    void intersect_rect(const Rect &rc);
    void union_rect(const Rect &rc);
    //void subtract_rect(const Rect &rc);

    bool empty() const;
    bool equal(const Rect &rc) const;
    bool pt_in_rc(dtype _x, dtype _y, bool include_boundary = true) const;
    bool is_intersect(const Rect &rc) const;

    dtype left() const;
    dtype top() const;
    dtype right() const;
    dtype bottom() const;
    Point center() const;
    Point left_top() const;
    Point left_bottom() const;
    Point right_top() const;
    Point right_bottom() const;
    Size size() const;
  };

  struct Matrix {
    dtype a,b,c,d,e,f;
    Matrix();
    Matrix(dtype _a, dtype _b, dtype _c, dtype _d, dtype _e, dtype _f);
    // clear to identity
    void clear();
    void reset(dtype _a, dtype _b, dtype _c, dtype _d, dtype _e, dtype _f);
    void multipy(const Matrix &matrix);
    void translate(dtype dx, dtype dy);
    void scale(dtype sx, dtype sy);
    void rotate(dtype angle);
    void transform(const Point &in, Point &out);

    bool identity() const;
    bool equal(const Matrix &matrix) const;
  };

  struct Color {
    uint8 a,r,g,b;
    Color();
    Color(cchar *name);
    Color(uint8 _a, uint8 _r, uint8 _g, uint8 _b);
    Color(dtype _a, uint8 _r, uint8 _g, uint8 _b);
    // clear alpha to 255
    void clear();
    void reset(cchar *name);
    void reset(uint8 _a, uint8 _r, uint8 _g, uint8 _b);
    void reset(dtype _a, uint8 _r, uint8 _g, uint8 _b);
  };
} // end namespace base

#endif // __BASE_BASE_H__